home *** CD-ROM | disk | FTP | other *** search
/ Aminet 31 / Aminet 31 (1999)(Schatztruhe)[!][Jun 1999].iso / Aminet / util / gnu / xpdf-0.8-src.lha / xpdf-0.8-src / ltk / LTKWindow.cc < prev    next >
C/C++ Source or Header  |  1998-11-28  |  13KB  |  479 lines

  1. //========================================================================
  2. //
  3. // LTKWindow.cc
  4. //
  5. // Copyright 1996 Derek B. Noonburg
  6. //
  7. //========================================================================
  8.  
  9. #ifdef __GNUC__
  10. #pragma implementation
  11. #endif
  12.  
  13. #include <stdlib.h>
  14. #include <stdarg.h>
  15. #include <stddef.h>
  16. #include <string.h>
  17. #include <X11/Xlib.h>
  18. #include <X11/Xutil.h>
  19. #include <X11/Xatom.h>
  20. #include <X11/cursorfont.h>
  21. #ifdef HAVE_X11_XPM_H
  22. #include <X11/xpm.h>
  23. #endif
  24. #include "LTKConfig.h"
  25. #include "LTKApp.h"
  26. #include "LTKMenu.h"
  27. #include "LTKWindow.h"
  28. #include "LTKWidget.h"
  29. #include "LTKBox.h"
  30. #include "LTKBorder.h"
  31.  
  32. #ifdef XlibSpecificationRelease
  33. #if XlibSpecificationRelease < 5
  34. typedef char *XPointer;
  35. #endif
  36. #else
  37. typedef char *XPointer;
  38. #endif
  39.  
  40. static Bool isExposeEvent(Display *display, XEvent *e, XPointer w);
  41.  
  42. LTKWindow::LTKWindow(LTKApp *app1, GBool dialog1, char *title1,
  43.              char **iconData1, char *defaultWidgetName,
  44.              LTKBox *box1) {
  45.   app = app1;
  46.   dialog = dialog1;
  47.   title = new GString(title1);
  48.   iconData = iconData1;
  49.   width = 0;
  50.   height = 0;
  51.   widgets = NULL;
  52.   box = box1;
  53.   box->setParent(this);
  54.   selection = NULL;
  55.   savedCursor = None;
  56.   busyCursorNest = 0;
  57.   menu = NULL;
  58.   keyCbk = NULL;
  59.   propCbk = NULL;
  60.   layoutCbk = NULL;
  61.   if (defaultWidgetName)
  62.     defaultWidget = findWidget(defaultWidgetName);
  63.   else
  64.     defaultWidget = NULL;
  65.   keyWidget = NULL;
  66.   selectionWidget = NULL;
  67.   pasteWidget = NULL;
  68.   overWin = NULL;
  69.   xwin = None;
  70.   eventMask = ExposureMask | StructureNotifyMask | VisibilityChangeMask |
  71.               ButtonPressMask | ButtonReleaseMask | KeyPressMask;
  72.   installCmap = gFalse;
  73.   fgGC = bgGC = brightGC = darkGC = xorGC = None;
  74.   fontStruct = NULL;
  75.   next = NULL;
  76.   app->addWindow(this);
  77. }
  78.  
  79. LTKWindow::~LTKWindow() {
  80.   if (xwin) {
  81.     XFreeFont(display, fontStruct);
  82.     XFreeGC(display, fgGC);
  83.     XFreeGC(display, bgGC);
  84.     XFreeGC(display, brightGC);
  85.     XFreeGC(display, darkGC);
  86.     XFreeGC(display, xorGC);
  87.     if (installCmap)
  88.       XFreeColormap(display, colormap);
  89.     XUnmapWindow(display, xwin);
  90.     XDestroyWindow(display, xwin);
  91.   }
  92.   app->setGrabWin(NULL);
  93.   app->delWindow(this);
  94.   delete title;
  95.   delete box;
  96.   if (selection)
  97.     delete selection;
  98.   if (menu)
  99.     delete menu;
  100. }
  101.  
  102. LTKWidget *LTKWindow::addWidget(LTKWidget *widget) {
  103.   widget->setNext(widgets);
  104.   widgets = widget;
  105.   return widget;
  106. }
  107.  
  108. LTKWidget *LTKWindow::delWidget(LTKWidget *widget) {
  109.   LTKWidget *w1, *w2;
  110.  
  111.   for (w1 = NULL, w2 = widgets;
  112.        w2 && w2 != widget;
  113.        w1 = w2, w2 = w2->getNext()) ;
  114.   if (w2 == widget) {
  115.     if (w1)
  116.       w1->setNext(w2->getNext());
  117.     else
  118.       widgets = w2->getNext();
  119.     w2->setNext(NULL);
  120.     return w2;
  121.   }
  122.   return NULL;
  123. }
  124.  
  125. LTKWidget *LTKWindow::findWidget(char *name) {
  126.   LTKWidget *widget;
  127.  
  128.   for (widget = widgets; widget; widget = widget->getNext()) {
  129.     if (widget->getName() && !strcmp(widget->getName(), name))
  130.       break;
  131.   }
  132.   return widget;
  133. }
  134.  
  135. void LTKWindow::setPropChangeCbk(LTKWindowPropCbk cbk) {
  136.   propCbk = cbk;
  137.   if (propCbk)
  138.     eventMask |= PropertyChangeMask;
  139.   else
  140.     eventMask &= ~PropertyChangeMask;
  141.   if (xwin != None)
  142.     XSelectInput(display, xwin, eventMask);
  143. }
  144.  
  145. GBool LTKWindow::checkFills(char **err) {
  146.   // outer box must either have both xfill > 0 and yfill > 0
  147.   // (i.e., the window is resizable), or xfill = yfill = 0
  148.   // (i.e., the window is not resizable)
  149.   if ((box->getXFill() > 0) != (box->getYFill() > 0)) {
  150.     *err = "outer box must have matched xfill and yfill";
  151.     return gFalse;
  152.   }
  153.  
  154.   // check consistency of box hierarchy
  155.   if (!box->checkFills(err))
  156.     return gFalse;
  157.  
  158.   // everything checked out ok
  159.   *err = "";
  160.   return gTrue;
  161. }
  162.  
  163. void LTKWindow::layout(int x, int y, int width1, int height1) {
  164.   XColor bgXcol;
  165.   XColor xcol;
  166.   XGCValues gcValues;
  167.   int minWidth, minHeight;
  168.   int width2, height2;
  169.   char *title1;
  170.   XSizeHints *sizeHints;
  171.   XWMHints *wmHints;
  172.   XClassHint *classHints;
  173.   XTextProperty windowName, iconName;
  174.   Atom protocol;
  175.   GBool newWin;
  176.  
  177.   // create window and GC's so widgets can use font info, etc.
  178.   if (xwin == None) {
  179.     newWin = gTrue;
  180.     display = app->getDisplay();
  181.     screenNum = app->getScreenNum();
  182.     fgColor = app->getColorResource("foreground", LTK_FOREGROUND,
  183.                     BlackPixel(display, screenNum), NULL);
  184.     bgColor = app->getColorResource("background", LTK_BACKGROUND,
  185.                     WhitePixel(display, screenNum), &bgXcol);
  186.     xwin = XCreateSimpleWindow(display, RootWindow(display, screenNum),
  187.                    (x < 0) ? 0 : x, (y < 0) ? 0 : y, 1, 1, 0,
  188.                    fgColor, bgColor);
  189.     app->registerXWindow(xwin, this, NULL);
  190.     XSelectInput(display, xwin, eventMask);
  191.     gcValues.foreground = fgColor;
  192.     gcValues.background = bgColor;
  193.     gcValues.line_width = 0;
  194.     gcValues.line_style = LineSolid;
  195.     gcValues.graphics_exposures = True;
  196.     fontStruct = app->getFontResource("font", LTK_WIN_FONT);
  197.     gcValues.font = fontStruct->fid;
  198.     fgGC = XCreateGC(display, xwin,
  199.              GCForeground | GCBackground | GCLineWidth | GCLineStyle |
  200.              GCGraphicsExposures | GCFont,
  201.              &gcValues);
  202.     gcValues.foreground = bgColor;
  203.     bgGC = XCreateGC(display, xwin,
  204.              GCForeground | GCBackground | GCLineWidth | GCLineStyle |
  205.              GCGraphicsExposures,
  206.              &gcValues);
  207.     gcValues.foreground = ltkGetBrightColor(display, screenNum,
  208.                         &bgXcol, fgColor);
  209.     brightGC = XCreateGC(display, xwin,
  210.              GCForeground | GCBackground | GCLineWidth |
  211.              GCLineStyle | GCGraphicsExposures,
  212.              &gcValues);
  213.     gcValues.foreground = ltkGetDarkColor(display, screenNum,
  214.                       &bgXcol, fgColor);
  215.     darkGC = XCreateGC(display, xwin,
  216.                GCForeground | GCBackground | GCLineWidth |
  217.                GCLineStyle | GCGraphicsExposures,
  218.                &gcValues);
  219.     gcValues.foreground = fgColor ^ bgColor;
  220.     gcValues.function = GXxor;
  221.     xorGC = XCreateGC(display, xwin,
  222.               GCForeground | GCBackground | GCLineWidth | GCLineStyle |
  223.               GCGraphicsExposures | GCFunction,
  224.               &gcValues);
  225.     colormap = DefaultColormap(display, screenNum);
  226.     if (installCmap) {
  227.       // ensure that BlackPixel and WhitePixel are reserved in the
  228.       // new colormap
  229.       xcol.red = xcol.green = xcol.blue = 0;
  230.       XAllocColor(display, colormap, &xcol);
  231.       xcol.red = xcol.green = xcol.blue = 65535;
  232.       XAllocColor(display, colormap, &xcol);
  233.       colormap = XCopyColormapAndFree(display, colormap);
  234.       XSetWindowColormap(display, xwin, colormap);
  235.     }
  236.   } else {
  237.     newWin = gFalse;
  238.   }
  239.  
  240.   // do layout
  241.   box->layout1();
  242.   minWidth = box->getWidth();
  243.   minHeight = box->getHeight();
  244.   if (box->getXFill() > 0 && box->getYFill() > 0) {
  245.     width2 = (width1 < minWidth) ? minWidth : width1;
  246.     height2 = (height1 < minHeight) ? minHeight : height1;
  247.     box->layout2(0, 0, width2, height2);
  248.   } else {
  249.     box->layout2(0, 0, minWidth, minHeight);
  250.   }
  251.   width = box->getWidth();
  252.   height = box->getHeight();
  253.  
  254.   // set the real window size
  255.   if (newWin)
  256.     XResizeWindow(display, xwin, width, height);
  257.  
  258.   // finish the layout and create the widget subwindows
  259.   box->layout3();
  260.  
  261.   // set window properties and protocols
  262.   if (newWin) {
  263.     sizeHints = XAllocSizeHints();
  264.     wmHints = XAllocWMHints();
  265.     classHints = XAllocClassHint();
  266.     if (sizeHints && wmHints && classHints) {
  267.       title1 = title->getCString();
  268.       XStringListToTextProperty(&title1, 1, &windowName);
  269.       XStringListToTextProperty(&title1, 1, &iconName);
  270.       sizeHints->flags = PMinSize;
  271.       sizeHints->flags |= (x >= 0 || y >= 0) ? USPosition : PPosition;
  272.       sizeHints->flags |= (width1 >= 0 || height1 >= 0) ? USSize : PSize;
  273.       sizeHints->min_width = minWidth;
  274.       sizeHints->min_height = minHeight;
  275.       if (!(box->getXFill() > 0 && box->getYFill() > 0)) {
  276.     sizeHints->flags |= PMaxSize;
  277.     sizeHints->max_width = minWidth;
  278.     sizeHints->max_height = minHeight;
  279.       }
  280.       wmHints->input = True;
  281.       wmHints->initial_state = NormalState;
  282.       wmHints->flags = InputHint | StateHint;
  283. #ifdef HAVE_X11_XPM_H
  284.       if (iconData) {
  285.     if (XpmCreatePixmapFromData(display, xwin, iconData,
  286.                     &wmHints->icon_pixmap, NULL, NULL) ==
  287.         XpmSuccess)
  288.       wmHints->flags |= IconPixmap